package com.chatroomdemo.controller;

import com.chatroomdemo.component.OnLineUserManager;
import com.chatroomdemo.mapper.MessageMapper;
import com.chatroomdemo.mapper.SessionMapper;
import com.chatroomdemo.model.Friend;
import com.chatroomdemo.model.Message;
import com.chatroomdemo.pojo.request.MessageRequest;
import com.chatroomdemo.pojo.response.MessageResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.List;

@Slf4j
@Component
public class WebSocketController extends TextWebSocketHandler {
    @Autowired
    private OnLineUserManager onLineUserManager;

    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    private SessionMapper sessionMapper;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        log.info("websocket 连接成功");
        Integer userId = (Integer) session.getAttributes().get("session_userId");
        if(userId == null){
            return;
        }
        onLineUserManager.online(userId,session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        log.info("websocket 收到消息" + message.toString());
        //1.获取用户信息
        Integer userId = (Integer) session.getAttributes().get("session_userId");
        String username = (String) session.getAttributes().get("session_username");
        if(userId == null || username == null){
            log.info("用户未登录,无法转发");
            return;
        }
        //2.解析请求,注意把json字符串转化为java对象
        MessageRequest req = objectMapper.readValue(message.getPayload(), MessageRequest.class);
        if(req.getType().equals("message")){
            //转发消息
            transferMessage(userId,username,req);
        }else {
            log.info("req.type 有误:" + message.getPayload());
        }
    }

    //通过这个方法进行转发
    private void transferMessage(Integer fromId, String fromName,MessageRequest req) throws IOException {
        //1.构造待转发的响应对象
        MessageResponse messageResponse = new MessageResponse("message",fromId,fromName, req.getSessionId(), req.getContent());
        //转成字符串
        String responseJson = objectMapper.writeValueAsString(messageResponse);
        log.info("转发消息：responseJson" + responseJson);
        //2.根据请求中的sessionId ,获取到message_session中有那些用户（查询数据库）
        List<Friend> friends = sessionMapper.selectFriendBySessionId(req.getSessionId(),fromId);
        //3.遍历users，通过OnLineUserManager获取到websocketsession发送响应,
        // ！！！也要给自己发送一个消息,因此需要将自己也加入friends,让自己可以看到自己发送的消息
        Friend myself = new Friend();
        myself.setFriendId(fromId);
        myself.setFriendName(fromName);
        friends.add(myself);
        for (Friend friend:friends
             ) {
            WebSocketSession webSocketSession = onLineUserManager.getSession(friend.getFriendId());
            if(webSocketSession == null){
                //用户不在线，不发送
                continue;
            }
            webSocketSession.sendMessage(new TextMessage(responseJson));
        }
        //4.转发的消息需要存储在数据库,这样下线之后，重新上线可以获取历史消息
        //向message表写入记录
        Message message = new Message();
        message.setFromId(fromId);
        message.setSessionId(req.getSessionId());
        message.setContent(req.getContent());
        messageMapper.insertMessage(message);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.info("websocket 连接异常" + exception.toString());
        Integer userId = (Integer) session.getAttributes().get("session_userId");
        if(userId == null){
            return;
        }
        onLineUserManager.offline(userId,session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        log.info("websocket 连接正常关闭" + status.toString());
        Integer userId = (Integer) session.getAttributes().get("session_userId");
        if(userId == null){   //userId没传！  这不就找到问题了嘛
            return;
        }
        onLineUserManager.offline(userId,session);
    }
}
